const DEFAULT_BASE = 17;

/**
 * 简单多项式哈希类
 * 用于创建字符串的哈希表示
 */
export default class SimplePolynomialHash {
  /**
   * 构造函数
   * 初始化多项式哈希使用的基数
   *
   * @param {number} [base] - 用于创建多项式的基数，默认为17
   */
  constructor(base = DEFAULT_BASE) {
    this.base = base;
  }

  /**
   * 创建给定单词的哈希表示
   *
   * 时间复杂度：O(word.length)
   *
   * 假设：此版本函数未使用取模运算符，可能会生成超过Number.MAX_SAFE_INTEGER的数字，导致溢出。
   * 此函数仅出于简化和学习目的。
   *
   * @param {string} word - 需要哈希的字符串
   * @return {number} - 字符串的哈希值
   */
  hash(word) {
    let hash = 0;
    for (let charIndex = 0; charIndex < word.length; charIndex += 1) {
      hash += word.charCodeAt(charIndex) * (this.base ** charIndex);
    }

    return hash;
  }

  /**
   * 根据前一个单词的哈希值重新计算当前单词的哈希表示
   *
   * 在移动一个字符后，基于前一个单词的哈希值进行重新计算，避免再次遍历整个单词。
   *
   * 时间复杂度：O(1)
   *
   * 假设：此函数未使用取模运算符，因此处理的数字可能超过Number.MAX_SAFE_INTEGER，存在溢出风险。
   * 此函数仅出于简化和学习目的。
   *
   * @param {number} prevHash - 前一个单词的哈希值
   * @param {string} prevWord - 前一个单词
   * @param {string} newWord - 新单词
   * @return {number} - 新单词的哈希值
   */
  roll(prevHash, prevWord, newWord) {
    let hash = prevHash;

    const prevValue = prevWord.charCodeAt(0);
    const newValue = newWord.charCodeAt(newWord.length - 1);

    hash -= prevValue;
    hash /= this.base;
    hash += newValue * (this.base ** (newWord.length - 1));

    return hash;
  }
}
